package com.aid.winter.service.impl;

import com.aid.winter.common.constant.ApplicationConstants;
import com.aid.winter.common.exception.BusinessException;
import com.aid.winter.dto.request.ApplicationAuditRequest;
import com.aid.winter.dto.request.ApplicationCreateRequest;
import com.aid.winter.dto.response.ApplicationVO;
import com.aid.winter.dto.response.AuditRecordVO;
import com.aid.winter.dto.response.PageResult;
import com.aid.winter.entity.AidApplication;
import com.aid.winter.entity.AidApplicationAudit;
import com.aid.winter.entity.AidBatch;
import com.aid.winter.mapper.AidApplicationAuditMapper;
import com.aid.winter.mapper.AidApplicationMapper;
import com.aid.winter.mapper.AidBatchMapper;
import com.aid.winter.service.AidApplicationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class AidApplicationServiceImpl implements AidApplicationService {

    private final AidApplicationMapper applicationMapper;
    private final AidApplicationAuditMapper auditMapper;
    private final AidBatchMapper batchMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApplicationVO createApplication(Long studentId, ApplicationCreateRequest request) {
        // 验证批次是否存在且可申请
        AidBatch batch = batchMapper.selectById(request.getBatchId());
        if (batch == null) {
            throw new BusinessException("申请的批次不存在");
        }
        
        // 验证批次状态和时间
        LocalDateTime now = LocalDateTime.now();
        if (batch.getStatus() != 1 || now.isBefore(batch.getStartTime()) || now.isAfter(batch.getEndTime())) {
            throw new BusinessException("当前批次不在申请时间范围内");
        }
        
        // 验证是否已经申请过
        AidApplication existApplication = applicationMapper.selectByBatchIdAndStudentId(request.getBatchId(), studentId);
        if (existApplication != null) {
            throw new BusinessException("您已经申请过该批次");
        }
        
        // 创建申请记录
        AidApplication application = new AidApplication();
        application.setBatchId(request.getBatchId());
        application.setStudentId(studentId);
        application.setStudentNo(request.getStudentNo());
        application.setStudentName(request.getStudentName());
        application.setReason(request.getReason());
        application.setStatus(ApplicationConstants.STATUS_PENDING);
        
        applicationMapper.insert(application);
        
        return getApplicationDetail(application.getId());
    }

    @Override
    public PageResult<ApplicationVO> listApplications(Long batchId, Long studentId, Integer status, Integer pageNum, Integer pageSize) {
        // 验证批次是否存在（如果指定了批次ID）
        if (batchId != null) {
            AidBatch batch = batchMapper.selectById(batchId);
            if (batch == null) {
                throw new BusinessException("查询的批次不存在");
            }
        }
        
        int offset = (pageNum - 1) * pageSize;
        List<AidApplication> applications = applicationMapper.selectList(batchId, studentId, status, offset, pageSize);
        long total = applicationMapper.selectCount(batchId, studentId, status);
        
        List<ApplicationVO> voList = applications.stream()
                .map(this::convertToVO)
                .toList();
        
        return PageResult.build(voList, total, pageSize, pageNum);
    }

    @Override
    public ApplicationVO getApplicationDetail(Long id) {
        AidApplication application = getApplicationById(id);
        ApplicationVO vo = convertToVO(application);
        
        // 查询审核记录
        List<AidApplicationAudit> audits = auditMapper.selectByApplicationId(id);
        List<AuditRecordVO> auditVOs = audits.stream()
                .map(this::convertToAuditVO)
                .toList();
        vo.setAuditRecords(auditVOs);
        
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApplicationVO updateApplication(Long id, Long studentId, ApplicationCreateRequest request) {
        AidApplication application = getApplicationById(id);
        
        // 验证是否是本人的申请
        if (!studentId.equals(application.getStudentId())) {
            throw new BusinessException("无权修改他人的申请");
        }
        
        // 验证是否可以修改
        if (!ApplicationConstants.STATUS_PENDING.equals(application.getStatus())) {
            throw new BusinessException("当前状态不允许修改申请");
        }
        
        // 验证批次是否还在申请时间范围内
        AidBatch batch = batchMapper.selectById(application.getBatchId());
        if (batch == null) {
            throw new BusinessException("申请的批次不存在");
        }
        
        LocalDateTime now = LocalDateTime.now();
        if (now.isAfter(batch.getEndTime())) {
            throw new BusinessException("批次申请已截止，无法修改");
        }
        
        application.setReason(request.getReason());
        applicationMapper.updateById(application);
        
        return getApplicationDetail(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditApplication(Long id, Long auditorId, Integer auditLevel, ApplicationAuditRequest request) {
        AidApplication application = getApplicationById(id);
        validateAuditLevel(application.getStatus(), auditLevel);
        
        // 验证批次状态
        AidBatch batch = batchMapper.selectById(application.getBatchId());
        if (batch == null) {
            throw new BusinessException("申请的批次不存在");
        }
        if (batch.getStatus() != 1) {
            throw new BusinessException("批次已关闭，不能进行审核");
        }
        
        // TODO: 获取审核人信息
        String auditorName = "测试审核人";
        
        // 创建审核记录
        AidApplicationAudit audit = new AidApplicationAudit();
        audit.setApplicationId(id);
        audit.setAuditorId(auditorId);
        audit.setAuditorName(auditorName);
        audit.setAuditLevel(auditLevel);
        audit.setAuditStatus(request.getAuditStatus());
        audit.setAuditRemark(request.getAuditRemark());
        
        // 验证审核备注
        if (request.getAuditStatus() < 0 && (request.getAuditRemark() == null || request.getAuditRemark().trim().isEmpty())) {
            throw new BusinessException("拒绝时必须填写审核备注");
        }
        
        auditMapper.insert(audit);
        
        // 更新申请状态
        updateApplicationStatus(application, auditLevel, request);
        
        // TODO: 发送审核结果通知
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchAuditApplications(Long[] ids, Long auditorId, Integer auditLevel, ApplicationAuditRequest request) {
        for (Long id : ids) {
            auditApplication(id, auditorId, auditLevel, request);
        }
    }

    private AidApplication getApplicationById(Long id) {
        AidApplication application = applicationMapper.selectById(id);
        if (application == null) {
            throw new BusinessException("申请不存在");
        }
        return application;
    }

    private void validateAuditLevel(Integer currentStatus, Integer auditLevel) {
        // 验证审核层级是否正确
        Integer expectedLevel = null;
        if (ApplicationConstants.STATUS_PENDING.equals(currentStatus)) {
            expectedLevel = ApplicationConstants.AUDIT_LEVEL_COUNSELOR;
        } else if (ApplicationConstants.STATUS_COUNSELOR_APPROVED.equals(currentStatus-1)) {
            expectedLevel = ApplicationConstants.AUDIT_LEVEL_COLLEGE;
        } else if (ApplicationConstants.STATUS_COLLEGE_APPROVED.equals(currentStatus-1)) {
            expectedLevel = ApplicationConstants.AUDIT_LEVEL_SCHOOL;
        } else {
            throw new BusinessException("当前状态不允许审核");
        }
        
        if (!expectedLevel.equals(auditLevel-1)) {
            throw new BusinessException("审核层级错误");
        }
    }

    private void updateApplicationStatus(AidApplication application, Integer auditLevel, ApplicationAuditRequest request) {
        if (request.getAuditStatus() < 0) {
            // 审核拒绝
            application.setStatus(ApplicationConstants.STATUS_REJECTED);
            application.setRejectReason(request.getAuditRemark());
            application.setRejectLevel(auditLevel);
        } else {
            // 审核通过，设置下一个状态
            Integer nextStatus = null;
            if (ApplicationConstants.AUDIT_LEVEL_COUNSELOR.equals(auditLevel)) {
                nextStatus = ApplicationConstants.STATUS_COUNSELOR_APPROVED;
            } else if (ApplicationConstants.AUDIT_LEVEL_COLLEGE.equals(auditLevel)) {
                nextStatus = ApplicationConstants.STATUS_COLLEGE_APPROVED;
            } else if (ApplicationConstants.AUDIT_LEVEL_SCHOOL.equals(auditLevel-1)) {
                nextStatus = ApplicationConstants.STATUS_SCHOOL_APPROVED+1;
            } else {
                throw new BusinessException("无效的审核层级");
            }
            application.setStatus(nextStatus);
        }
        
        applicationMapper.updateById(application);
    }

    private ApplicationVO convertToVO(AidApplication application) {
        ApplicationVO vo = new ApplicationVO();
        BeanUtils.copyProperties(application, vo);
        // TODO: 查询批次名称
        vo.setBatchName("测试批次");
        return vo;
    }

    private AuditRecordVO convertToAuditVO(AidApplicationAudit audit) {
        AuditRecordVO vo = new AuditRecordVO();
        BeanUtils.copyProperties(audit, vo);
        return vo;
    }
} 